package top.llove.common.utils.file.fastdfs;

import org.apache.catalina.security.SecurityUtil;
import org.csource.common.MyException;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.YamlMapFactoryBean;
import org.springframework.boot.json.YamlJsonParser;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.multipart.MultipartFile;
import org.yaml.snakeyaml.Yaml;
import top.llove.common.utils.SecurityUtils;
import top.llove.common.utils.StringUtils;
import top.llove.framework.aspectj.LogAspect;
import top.llove.framework.config.AdminConfig;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

/**
 * FastDFS操作
 *
 * @author: 幸会
 * @date: 2021/11/18 17:28
 * @email: 1846724873@qq.com
 * @description: FastDFS操作
 * @version: 1.0
 */
public class FastDFSUtils {
    private static final Logger log = LoggerFactory.getLogger(FastDFSUtils.class);
    /** TrackerClient */
    private static TrackerClient trackerClient = null;
    /** TrackerServer */
    private static TrackerServer trackerServer = null;
    /** StorageServer */
    private static StorageServer storageServer = null;
    /** StorageClient */
    private static StorageClient storageClient = null;
    static {
        try {
            String configPath = new ClassPathResource("fast_dfs.conf").getFile().getAbsolutePath();
            ClientGlobal.init(configPath);
            // 客户端对象
            trackerClient = new TrackerClient();
            // 获取链接
            trackerServer = trackerClient.getTrackerServer();
            // 获取StorageServer
            storageServer = trackerClient.getStoreStorage(trackerServer);
            // 获取StorageClient
            storageClient = new StorageClient(trackerServer, storageServer);

        } catch (IOException e) {
            e.printStackTrace();
        } catch (MyException e) {
            e.printStackTrace();
        }
    }


    /**
     * 文件上传
     * @author 幸会
     * @date 2021/11/18 17:53
     * @param filename 文件名
     * @param ext 后缀名
     * @param content 文件内容
     * @param avatar 作者
     * @return java.util.Map<java.lang.String,java.lang.String>
     */
    public static Map<String, Object> upload(String filename, String ext, byte[] content, String avatar) throws MyException, IOException {
        FastDFSFile file = new FastDFSFile();
        // 文件名
        file.setName(filename);
        // 后缀名
        file.setExt(ext);
        // 文件内容
        file.setContent(content);
        // 作者
        file.setAuthor(avatar);
        return upload(file);
    }

    /**
     * 文件上传
     * @author 幸会
     * @date 2021/11/18 17:46
     * @param file
     * @return java.util.Map<java.lang.String,java.lang.String>
     */
    public static Map<String, Object> upload(MultipartFile file) throws MyException, IOException {
        FastDFSFile fastDFSFile = new FastDFSFile();
        // 获取文件名
        String filename = file.getOriginalFilename();
        fastDFSFile.setName(filename);
        // 获取后缀名
        String ext = filename.substring(filename.lastIndexOf(".") + 1);
        fastDFSFile.setExt(ext);
        // 文件内容
        byte[] content = file.getBytes();
        fastDFSFile.setContent(content);
        // 作者
        String avatar = SecurityUtils.getUsername();
        fastDFSFile.setAuthor(avatar);

        // 文件大小
        fastDFSFile.setSize(file.getSize());
        return upload(fastDFSFile);
    }
    /**
     * 上传文件
     * @author 幸会
     * @date 2021/11/18 17:31
     * @param file
     * @return java.lang.String[]
     */
    public static Map<String, Object> upload (FastDFSFile file) throws MyException, IOException {

        // 文件上传附加信息
        NameValuePair[] meta = new NameValuePair[1];

        // 上传者
        meta[0] = new NameValuePair("author", file.getAuthor());

        // 上传文件
        String[] upload = storageClient.upload_file(file.getContent(), file.getExt(), meta);

        if (StringUtils.isNull(upload)) {
            throw new NullPointerException("上传失败！");
        }
        Map<String, Object> res = new HashMap<>();
        // 组名
        res.put("group", upload[0]);
        // 文件名
        res.put("file_new_name", upload[1]);
        // 原文件名
        res.put("file_old_name", file.getName());
        // 链接
        res.put("url", AdminConfig.getFilePrefix() + upload[0] + "/" + upload[1]);
        // 后缀
        res.put("ext", file.getExt());
        // 文件大小
        res.put("size", file.getSize());
        return res;
    }


    /**
     * 获取文件信息
     * @author 幸会
     * @date 2021/11/18 17:47
     * @param groupName
     * @param remoteFileName
     * @return org.csource.fastdfs.FileInfo
     */
    public static FileInfo getFile(String groupName, String remoteFileName) {
        try {
            storageClient = new StorageClient(trackerServer, storageServer);
            return storageClient.get_file_info(groupName, remoteFileName);
        } catch (IOException e) {
            log.error("IO Exception: Get File from Fast DFS failed", e);
        } catch (Exception e) {
            log.error("Non IO Exception: Get File from Fast DFS failed", e);
        }
        return null;
    }

    /**
     * 下载文件
     * @author 幸会
     * @date 2021/11/18 17:48
     * @param groupName 组名
     * @param remoteFileName 文件名
     * @return java.io.InputStream
     */
    public static InputStream download(String groupName, String remoteFileName) {
        try {
            storageClient = new StorageClient(trackerServer, storageServer);
            byte[] fileByte = storageClient.download_file(groupName, remoteFileName);
            InputStream ins = new ByteArrayInputStream(fileByte);
            return ins;
        } catch (IOException e) {
            log.error("IO Exception: Get File from Fast DFS failed", e);
        } catch (Exception e) {
            log.error("Non IO Exception: Get File from Fast DFS failed", e);
        }
        return null;
    }


    /**
     * 删除文件
     * @author 幸会
     * @date 2021/11/18 17:49
     * @param groupName
     * @param remoteFileName
     */
    public static void deleteFile(String groupName, String remoteFileName)
            throws Exception {
        storageClient = new StorageClient(trackerServer, storageServer);
        int i = storageClient.delete_file(groupName, remoteFileName);
        log.error("文件{}删除成功, {}", (groupName + remoteFileName), i);
    }
}
